package cbbx_sm.utils;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cbbx_sm.parser.BoundingBox;
import cbbx_sm.parser.CameraData;
import cbbx_sm.parser.Entity;
import cbbx_sm.parser.Frame;
import cbbx_sm.parser.Parser;
import cbbx_sm.probabilistic_model.Cluster;
import cbbx_sm.probabilistic_model.Clustering;


public class ClustersGenerator {
	public static void main(String[] args) throws IOException{
		new MainThread().start();
	}
}

class MainThread extends Thread {
//	private String[] fileNames = {"2009052814.txt", "2009052813.txt",
//								  "2009052815.txt", "2009052816.txt",
//								  "2009052817.txt", "2009052818.txt",};
	
	public void run(){
		KruskalThread kt;

		System.out.println("Starting...");
		try {
			kt = new KruskalThread("2009052813.txt", 150.0);
			kt.start();
			kt.join();
			System.gc();
			System.out.println("JOINATO...");
		
			kt = new KruskalThread("2009052814.txt", 150.0);
			kt.start();
			kt.join();
			System.gc();
			System.out.println("JOINATO...");
			
			kt = new KruskalThread("2009052815.txt", 150.0);
			kt.start();
			kt.join();
			System.gc();
			System.out.println("JOINATO...");
			
			kt = new KruskalThread("2009052816.txt", 150.0);
			kt.start();
			kt.join();
			System.gc();
			System.out.println("JOINATO...");
			
			kt = new KruskalThread("2009052817.txt", 150.0);
			kt.start();
			kt.join();
			System.gc();
			System.out.println("JOINATO...");
			
			kt = new KruskalThread("2009052818.txt", 150.0);
			kt.start();
			kt.join();
			System.gc();
			System.out.println("JOINATO...");
			
//			kt = new KruskalThread("2009052713.txt", 125.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//		
//			kt = new KruskalThread("2009052714.txt", 125.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052715.txt", 125.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052716.txt", 125.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052717.txt", 125.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052718.txt", 125.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052713.txt", 150.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//		
//			kt = new KruskalThread("2009052714.txt", 150.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052715.txt", 150.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052716.txt", 150.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052717.txt", 150.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052718.txt", 150.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052713.txt", 175.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//		
//			kt = new KruskalThread("2009052714.txt", 175.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052715.txt", 175.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052716.txt", 175.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052717.txt", 175.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052718.txt", 175.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052713.txt", 200.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//		
//			kt = new KruskalThread("2009052714.txt", 200.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052715.txt", 200.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052716.txt", 200.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052717.txt", 200.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
//			
//			kt = new KruskalThread("2009052718.txt", 200.0);
//			kt.start();
//			kt.join();
//			System.gc();
//			System.out.println("JOINATO...");
		}
		catch (IOException e) {
			e.printStackTrace();
		} 
		catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class KruskalThread extends Thread {
	
	private double THRESHOLD = 150.0;
	
	private String fileName;
	private OutputStreamWriter out;
	private CameraData data;
	private Set<BoundingBox> boxes = new HashSet<BoundingBox>();
	
	public KruskalThread(String filename, double THRESHOLD) throws IOException{
		this.fileName = filename;
		this.THRESHOLD = THRESHOLD;
		data = Parser.parseFile("data/cameraData/" + filename, "data/cameraData/" + filename);
		
		for (Frame f : data.getFrames())
			for(Entity e : f.getEntities())
				boxes.add(e.getBoxes()[ExperimentManager.boxLocationId]);
	}
	
	@Override
	public void run(){
		long ti = System.currentTimeMillis();
		System.out.println("STARTED Kruskal Computation for " + fileName + " ...");
		List<Cluster> clusters = Clustering.kruskalClustering(boxes, THRESHOLD);
		System.out.println("FINISHED Kruskal Computation for " + fileName + "!!!");
		long to = System.currentTimeMillis();
		long millis = to - ti;
		float minutes = ((float) millis) / 60000;
		
		try {
			out = new OutputStreamWriter(new FileOutputStream("output/Kruskal_" + THRESHOLD + "_" + fileName));
			out.write("****** Kruskal Clustering started at: " + ti + " \n");
			out.write("****** Kruskal Clustering finished at: " + to + " \n");
			out.write("****** Clusters found: \n");
			for (Cluster c : clusters){
				out.write("\tCLUSTER: (" + c.getX() + "; " + c.getY() + ") RADIUS: " + c.getRadius() + "\n");
			}
			out.write("****** Kruskal Clustering total time: " + minutes + " \n");
			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
